#include <iostream>
#include <unistd.h>
using namespace std;

class Date{
	private:
		int _year;
		int _month;
		int _day;
	private:
		int MonthDay(int year, int month)
		{
			int Days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
			if(0 == year%400 || (0 == year%4 && 0 != year%100)) {
				return Days[month] + 1;
			}
			return Days[month];
		}
	public:
		friend ostream& operator<<(ostream& _cout, const Date& d);
		Date(int year = 2018, int month = 9, int day = 22)
			: _year(year)
			, _month(month)
			, _day(day)
		{
			if(_month > 12 || _month < 0 || _day > MonthDay(_year, _month) || _day < 0)
				cout << "Invalid Date!" << endl;
			return;
		}

		Date(const Date& d)
		{
			_year = d._year;	
			_month = d._month;
			_day = d._day;
		}

		Date& operator=(const Date& d)
		{
			if(this != &d) {
				_year = d._year;	
				_month = d._month;
				_day = d._day;
			}
			return *this;
		}

		void SetDate()
		{
			cout << "Year :" << endl;
			cin >> _year;

			cout << "Month :" << endl;
			while(cin >> _month) {
				if(_month > 12 || _month < 1)
					cout << "Try Again!" << endl;
				else
					break;
			}

			cout << "Day :" << endl;
			while(cin >> _day) {
				if(_day > MonthDay(_year, _month) || _day < 1)
					cout << "Try Again!" << endl;
				else
					break;
			}

			cout << "Set OK!" << endl;
		}
		// sub or add
		Date operator+(int days)
		{
			if(days < 0) {
				return (*this - days);
			}
			Date temp(*this);
			if(days == 0) {
				return temp;
			}
			int month_day = MonthDay(temp._year, temp._month);
			temp._day += days;
			while(temp._day > month_day) {
				temp._month += 1;
				temp._day -= month_day;

				if(temp._month > 12) {
					temp._month = 1;
					temp._year += 1;
				}
			}
			return temp;
		}

		// += 运算符重载调用+运算符重载
		Date& operator+=(int days)
		{
			Date temp(*this);
			temp = (*this) + days;
			*this = temp;
			return *this;
		}

		Date operator-(int days)
		{
			if(days < 0) {
				return (*this + days);
			}

			Date temp(*this);
			if(days == 0) {
				return temp;
			}
			temp._day -= days;
			while(temp._day < 0) {
				temp._day += MonthDay(temp._year, temp._month);
				temp._month -= 1;
				if(temp._month < 0) {
					temp._month += 1;
					temp._year -= 1;
				}
			}
			return temp;
		}

		Date& operator-=(int days)
		{
			Date temp(*this);
			temp = (*this) - days;
			*this = temp;
			return *this;
		}

		Date operator++(int)
		{
			Date temp(*this);
			*this += 1;
			return temp;
		}

		Date& operator++()
		{
			*this += 1;
			return *this;
		}

		Date operator--(int)
		{
			Date temp(*this);
			*this -= 1;
			return temp;
		}

		Date& operator--()
		{
			*this -= 1;
			return *this;
		}

		bool IsLeapYear(int year)
		{
			return (0 == year%400 || (0 == year%4 && 0 != year%4));
		}

		// 计算日期之差
		int operator-(const Date& d)
		{
			if(*this == d)
				return 0;
			Date first(*this);
			Date second(d);
			int day = 0;
			if(first < second) {
				while((first + day) < second)
				{
					++day;
				}
				return day;
			}
			if(first > second) {
				while((second + day) < first)
				{
					++day;
				}
				return day;
			}
			return 0;
		}

		// compare
		bool operator==(const Date& d)
		{
			return _year == d._year && _month == d._month && _day == d._day;
		}

		bool operator!=(const Date& d)
		{
			return !(*this == d);
		}

		bool operator>(const Date& d)
		{
			if(_year == d._year && _month == d._month && _day == d._day)
				return false;;

			if(_year > d._year) {
				return true;
			}
			if(_year == d._year) {
				if(_month > d._month) {
					return true;
				}
				if(_month == d._month) {
					if(_day > d._day) {
						return true;
					}
				}
			}
			return false;
		}

		bool operator<(const Date& d)
		{
			if(_year == d._year && _month == d._month && _day == d._day)
				return false;;
			if(_year < d._year)
				return true;
			if(_year == d._year) {
				if(_month < d._month) {
					return true;
				}
				if(_month == d._month) {
					if(_day < d._day) {
						return true;
					}
				}
			}
			return false;
		}

		bool operator>=(const Date& d)
		{
			return !(*this < d);
		}
		bool operator<=(const Date& d)
		{
			return !(*this > d);
		}

		~Date()
		{}
};

ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day << endl;
	return _cout;
}

void TestDate()
{
	//调用构造函数 或 设置时间方法
	Date d1;
	//d1.SetDate();
	cout << "d1 : " << d1;

	//拷贝构造函数
	Date d2(d1);
	cout << "d2 : " << d2;

	//拷贝构造函数
	Date d3;
	d3 = d2;
	cout << "d3 : " << d3;

	d3 += 100;
	cout << "d3 : " << d3;
	d2 -= 100;
	cout << "d2 : " << d2;

	cout << d3 - d2 << endl;
}

int main()
{
	TestDate();
	return 0;
}
